package com.subfg.payment.util.ali.mode.impl;

import com.alipay.api.AlipayClient;
import com.alipay.api.domain.*;
import com.alipay.api.request.*;
import com.alipay.api.response.*;
import com.subfg.common.entity.call.request.RequestPayModel;
import com.subfg.common.entity.call.request.RequestTransferModel;
import com.subfg.common.entity.call.request.refund.ApplyRefundModel;
import com.subfg.common.entity.call.result.ResultPayModel;
import com.subfg.common.entity.config.pay.ConfigPayAliModel;
import com.subfg.common.entity.excpetion.BusinessExceptionModel;
import com.subfg.payment.util.ali.mode.AliPayModeServer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Component
public class AliPayModeServerImpl implements AliPayModeServer {
    private Logger log = LoggerFactory.getLogger(AliPayModeServer.class);

    private final static String  ALIPAY_LOGON_ID = "ALIPAY_LOGON_ID";
    private final static String TRANS_ACCOUNT_NO_PWD = "TRANS_ACCOUNT_NO_PWD";
    private final static String DIRECT_TRANSFER = "DIRECT_TRANSFER";

    @Override
    public ResultPayModel createAppAliPayInfo(RequestPayModel payInfo, ConfigPayAliModel configPayAliModel, AlipayClient client) throws BusinessExceptionModel {
        log.info("生成支付宝APP端支付信息");
        AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
        request.setApiVersion("2.0");
        request.setNotifyUrl(configPayAliModel.getPayNotifyUrl());
        model.setOutTradeNo(payInfo.getOrderNo());
        model.setTotalAmount(String.valueOf(payInfo.getAmount()));
        model.setSubject(payInfo.getDescribe());
        model.setBody((String) payInfo.getAttach());
        try {
            request.setBizModel(model);
            AlipayTradeAppPayResponse response = client.sdkExecute(request);
            return new ResultPayModel(response.getBody(), payInfo.getOrderNo(), payInfo.getAmount());
        } catch (Exception e) {
            log.error("支付宝生成 APP支付信息错误==>>>{}", e.toString());
            throw new BusinessExceptionModel();
        }
    }

    @Override
    public ResultPayModel createWebPagePayInfo(RequestPayModel payInfo, ConfigPayAliModel configPayAliModel, AlipayClient client) throws BusinessExceptionModel {
        log.info("生成支付宝WEB端支付信息");
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
        AlipayTradePagePayModel model = new AlipayTradePagePayModel();
        request.setNotifyUrl(configPayAliModel.getPayNotifyUrl());
        model.setOutTradeNo(payInfo.getOrderNo());
        model.setTotalAmount(String.valueOf(payInfo.getAmount()));
        model.setSubject(payInfo.getDescribe());
        model.setProductCode("FAST_INSTANT_TRADE_PAY");
        model.setBody((String) payInfo.getAttach());
        request.setBizModel(model);
        try {
            AlipayTradePagePayResponse response = client.pageExecute(request);
            log.info(response.getBody());
            return new ResultPayModel(response.getBody(), payInfo.getOrderNo(), payInfo.getAmount());
        } catch (Exception e) {
            log.error("支付宝生成 WEB 支付信息错误==>>>{}", e.toString());
            throw new BusinessExceptionModel();
        }
    }

    @Override
    public ResultPayModel createQrcodePayInfo(RequestPayModel payInfo, ConfigPayAliModel configPayAliModel, AlipayClient client) throws BusinessExceptionModel {
        log.info("生成支付宝QRCODE支付信息");
        AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
        AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
        request.setNotifyUrl(configPayAliModel.getPayNotifyUrl());
        model.setOutTradeNo(payInfo.getOrderNo());
        model.setTotalAmount(String.valueOf(payInfo.getAmount()));
        //  TODO 测试时修改订单支付金额
        // model.setTotalAmount("0.01");
        model.setSubject(payInfo.getDescribe());
        model.setBody((String) payInfo.getAttach());
        request.setBizModel(model);
        try {
            AlipayTradePrecreateResponse response = new AlipayTradePrecreateResponse();
            // 普通密钥模式
            if (configPayAliModel.getType().equals(1)) {
                response = client.execute(request);
                // 证书模式
            } else if (configPayAliModel.getType().equals(2)) {
                response = client.certificateExecute(request);
            }
            return new ResultPayModel(response.getQrCode(), payInfo.getOrderNo(), payInfo.getAmount());
        } catch (Exception e) {
            log.error("支付宝生成 QRCODE 支付信息错误==>>>{}", e.toString());
            throw new BusinessExceptionModel();
        }
    }

    // 退款
    @Override
    public AlipayTradeRefundResponse alipayRefund(ApplyRefundModel.RefundOrderModel refundOrderModel, ConfigPayAliModel configPayAli, AlipayClient client) throws BusinessExceptionModel {
        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
        AlipayTradeRefundModel refundModel = new AlipayTradeRefundModel();
        refundModel.setTradeNo(refundOrderModel.getChannelNo());
        log.info("正在使用支付宝申请退费服务, 订单号是{}, 退款订单号{}, 退费金额为{}", refundOrderModel.getOrderNo(), refundOrderModel.getRefundNo(), refundOrderModel.getComputeRefundAmount());
        refundModel.setRefundAmount(String.valueOf(refundOrderModel.getComputeRefundAmount()));
        refundModel.setOutRequestNo(refundOrderModel.getRefundNo());
        request.setBizModel(refundModel);
        try {
            AlipayTradeRefundResponse refundResponse = new AlipayTradeRefundResponse();
            if (configPayAli.getType() == 1) {
                // 密钥模式
                refundResponse = client.execute(request);
            } else if (configPayAli.getType() == 2){
                // 证书模式
                refundResponse = client.certificateExecute(request);
            }
            return refundResponse;
        } catch (Exception e ) {
            log.error("支付宝配置或网络等原因导致失败! 请检查:==>>>"+e);
            throw new BusinessExceptionModel();
        }
    }

    // 转账
    // TODO 需阅读支付宝文档
    @Override
    public AlipayFundTransUniTransferResponse aliTransfer(RequestTransferModel transferModel, ConfigPayAliModel configPayAliModel, AlipayClient client) throws BusinessExceptionModel {
        if (configPayAliModel.getType() == null || configPayAliModel.getType().equals(1)) {
            throw new BusinessExceptionModel();
        }
        AlipayFundTransUniTransferRequest request = new AlipayFundTransUniTransferRequest();
        AlipayFundTransUniTransferModel model = new AlipayFundTransUniTransferModel();
        // 收款方个人信息
        Participant participant = new Participant();
        participant.setIdentity(transferModel.getSensitiveInformation()); // 收款方账号
        participant.setName(transferModel.getSupplementaryInformation()); // 真实姓名
        participant.setIdentity(ALIPAY_LOGON_ID);

        model.setTransAmount(String.valueOf(transferModel.getTransferAmount()));

        model.setProductCode(TRANS_ACCOUNT_NO_PWD);
        model.setBizScene(DIRECT_TRANSFER);

        model.setPayeeInfo(participant);                   // 转账方信息
        model.setOrderTitle(transferModel.getSubject());  // 转账备注
        model.setOutBizNo(transferModel.getOrderNo());    //转账单号
        request.setBizModel(model);
        try {
            AlipayFundTransUniTransferResponse response = client.certificateExecute(request);
            return  response;
        } catch (Exception e ) {
            log.error("支付宝配置或网络等原因导致失败! 请检查:==>>>"+e);
            throw new BusinessExceptionModel();
        }
    }
}
